package com.tohours.aia.service.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import lombok.Data;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springside.modules.orm.Page;

import com.tohours.aia.constants.Constants;
import com.tohours.aia.dao.CustomerDao;
import com.tohours.aia.dao.GiftCountDao;
import com.tohours.aia.dao.GiftLogDao;
import com.tohours.aia.entity.Customer;
import com.tohours.aia.entity.GiftLog;
import com.tohours.aia.exception.BusinessException;
import com.tohours.aia.service.AwardService;

@Service
@Transactional
public @Data class AwardServiceImpl implements AwardService{

	@Autowired
	private CustomerDao customerDao;
	@Autowired
	private GiftCountDao giftCountDao;
	@Autowired
	private GiftLogDao giftLogDao;

	public Customer login(String idOrSplit) {
		Assert.notNull(idOrSplit);
		StringBuffer hql  = new StringBuffer();
		hql.append(" from Customer where slipNumber = ? or customerId = ?");
		List<Customer> list = customerDao.find(hql.toString(), idOrSplit, idOrSplit);
		if(list.size() > 0){
			Customer customer = list.get(0);
			if(isCurrentBirthday(customer.getBirthday())){
				return customer;
			} else {
				throw new BusinessException("谢谢您对我们的关注，您尚未获得抽奖资格，请询问您的保险顾问。");
			}
		} else {
			throw new BusinessException("请输入您在2013年11月15号前留下的保单号或证件号码");
		}
	}

	public Customer getCustomer(String id) {
		Assert.notNull(id);
		Customer customer = customerDao.get(id);
		if(customer != null && customer.getTotalChance() == null){
			countTotalAndLeft(customer);
		}
		return customer;
	}
	
	private void countTotalAndLeft(Customer customer){
		Long total = 0L;
		if("Y".equals(customer.getActive())){
			total += 1;
		}
		
		Date birthday = customer.getBirthday();
		if(isCurrentBirthday(birthday)){
			total += 1;
		}
		customer.setTotalChance(total);
		customer.setLeftChance(total);
		customerDao.save(customer);
	}
	
	private boolean isCurrentBirthday(Date birthday){
		Assert.notNull(birthday);
		Calendar c = Calendar.getInstance();
		c.setTime(birthday);
		int month = c.get(Calendar.MONTH);
		if(month >= 11 || month <= 1){
			return true;
		} else {
			return false;
		}
	}
	
	public GiftLog loterry(String customerId){
		Customer customer = customerDao.get(customerId);
		if(customer.getLeftChance() > 0){
			Long gift = null;
			if(customer.getLeftChance() < 2){
				Map<Long, Long> map = countLeft();
				gift = random(map);
			} else {
				gift = Constants.GIFT_YHD;
			}
			GiftLog gl = updateStatus(gift, customerId);
			return gl;
		} else {
			throw new BusinessException("你的抽奖机会已经用完！");
		}
	}


	/**
	 * 更新礼品的数量
	 * @param gift 礼品编号
	 */
	private GiftLog updateStatus(Long giftCode, String customerId) {
		
		//记录礼品日志
		GiftLog gl = new GiftLog();
		gl.setCustomerId(customerId);
		gl.setExchangeFlag(false);
		gl.setGiftCode(giftCode);
		Date now = new Date();
		gl.setInsertTime(now);
		gl.setUpdateTime(now);
		giftLogDao.save(gl);
		
		//记录剩余机会数
		Customer customer = customerDao.get(customerId);
		customer.setLeftChance(customer.getLeftChance() - 1);
		customerDao.save(customer);
		
		// 记录礼品数量
		if (!Constants.GIFT_YHD.equals(giftCode)) {

			Calendar c = Calendar.getInstance();
			int month = c.get(Calendar.MONTH) + 1;
			String hql = "update GiftCount gc set gc.count = gc.count - 1 where giftCode = ? and month = ?";
			giftCountDao.batchExecute(hql, giftCode, Long.valueOf(month));
		}
		return gl;
	}

	/**
	 * 统计剩余的礼品数
	 * @return
	 */
	private Map<Long, Long> countLeft() {
		Calendar c = Calendar.getInstance();
		int month = c.get(Calendar.MONTH) + 1;
		String where = getWhere(month);
		Set<Long> keys = Constants.GIFT.keySet();
		Iterator<Long> it = keys.iterator();
		Map<Long, Long> map = new HashMap<Long, Long>();
		while(it.hasNext()){
			Long gift = it.next();
			if(!Constants.GIFT_YHD.equals(gift)){
				String hql = "select sum(gc.count) from GiftCount gc where giftCode = " + gift + where;
				List<Long> list = giftCountDao.find(hql);
				Assert.isTrue(list.size() > 0);
				Long left = list.get(0);
				if(left <= 0){
					map.put(gift, 0L);
				}
			}
		}
		return map;
	}

	/**
	 * 根据月份获得条件
	 * @param month
	 * @return
	 */
	private String getWhere(int month) {

		String where = "";
		switch (month) {
		case 11:
		case 12:
			where = " and month = 12";
			break;
		case 1:
			where = " and (month = 12 or month = 1)";
			break;
		case 2:
			where = " and (month = 12 or month = 1 or month = 2)";
			break;
		case 3:
			where = " and (month = 12 or month = 1 or month = 2 or month = 3)";
			break;
		case 4:
			where = " and (month = 12 or month = 1 or month = 2 or month = 3 or month = 4)";
			break;
		case 5:
			where = " and (month = 12 or month = 1 or month = 2 or month = 3 or month = 4 or month = 5)";
			break;
		default:
			throw new BusinessException("月份不在范围内！");
		}
		return where;
	}
	
	/**
	 * 抽奖，可修改中奖参数，默认参数为GIFT_PERCENT
	 * @param map
	 * @return
	 */
	private  Long random(Map<Long, Long> map){
		long round = Math.round(Math.random() * 10000);
		long current = 10000;
		for (int i = Constants.GIFT_PERCENT.length - 1; i > 0; i--) {
			if(map != null && map.get(Long.valueOf(i + 1)) != null){
				current -= map.get(Long.valueOf(i + 1));
			} else {
				current -= Constants.GIFT_PERCENT[i];
			}
			if (current < round) {
				return Long.valueOf(i + 1);
			}
		}
		return 1L;
	}

	public Page<GiftLog> searchGiftLog(Map<String, Object> key,
			Page<GiftLog> page) {
		StringBuffer hql = new StringBuffer();
		hql.append(" from GiftLog where 1=1");
		Map<String, Object> values = new HashMap<String, Object>();
		if(key != null){
			String customerId = (String)key.get("customerId");
			hql.append(" and customerId = :customerId");
			values.put("customerId", customerId);
		}
		return giftLogDao.findPage(page, hql.toString(), values);
	}

	public GiftLog getGiftLog(String id) {
		Assert.notNull(id);
		return giftLogDao.get(id);
	}

	public GiftLog editGiftLog(GiftLog giftLog) {
		Assert.notNull(giftLog);
		Assert.notNull(giftLog.getId());
		GiftLog dbg = giftLogDao.get(giftLog.getId());
		if(giftLog.getExchangeFlag() != null){
			dbg.setExchangeFlag(giftLog.getExchangeFlag());
		}
		if(giftLog.getExchangeCode() != null){
			dbg.setExchangeCode(giftLog.getExchangeCode());
		}
		dbg.setUpdateTime(new Date());
		giftLogDao.save(dbg);
		return null;
	}
}
